#ifndef CATIMAGE_H
#define CATIMAGE_H
#include <gtkmm-2.4/gtkmm.h>
#include <glibmm-2.4/glibmm.h>
#include <gdkmm-2.4/gdkmm.h>
#include <gdkmm-2.4/gdkmm/pixbuf.h>
#include <iostream>
#include <libgnomevfs/gnome-vfs.h>
#include <vector>
#include <string>
#include <list>
#include <Magick++.h>
#include <boost/tokenizer.hpp>
#include <pthread.h>
#include "labelFactory.cpp"
#include "mysql/mysql.h"
using namespace boost;
using namespace std;
using namespace Magick;
class catImage
{
	protected:
		vector<string> tags;
		string title;
		string workingDirectory;
		Glib::RefPtr<Gdk::Pixbuf> image;
		Glib::RefPtr<Gdk::Pixbuf> scaledInstance;
		Glib::ustring pathname;
		bool hsi;
		int sw,sh;
		Image imImage;
		Image simImage; 
		vector<string> splitTags(string tags)
		{
			vector<string> results;
			tokenizer<> t(tags);
			for(tokenizer<>::iterator b=t.begin();b!=t.end();++b)
			{
				results.push_back(*b);
			}
			return results;
		}

		void loadImage()
		{
			image = Gdk::Pixbuf::create_from_file(pathname);
		}

		void clearImage()
		{
			image.clear();
		}



	public:
		catImage(Glib::ustring fname, Glib::ustring wdr=".") : hsi(0)
		{
			pathname = wdr+"/"+fname;
			setTitle(fname);
			image = Gdk::Pixbuf::create_from_file(pathname);
			imImage.read(pathname);
		}

		bool hasScaled(){return hsi;}

		int save(string s)
		{
			imImage.write(s);
		}

		void save()
		{
			imImage.write(pathname);
		}

		void saveAs(string pname)
		{
			imImage.write(pname);
		}

		int blurImage()
		{
			imImage.implode(15);
			imImage.write(pathname+".tmp");
			image = Gdk::Pixbuf::create_from_file(pathname+".tmp");
			string tst("rm ");
			tst.append(pathname.c_str());
			tst.append(".tmp");
			system(tst.c_str());
			if(hsi)
			{
				cout<<"sw: "<<sw<<endl<<"sh: "<<sh<<endl;
				scale(sw,sh);
			}
		}
		
		static bool checkType(Glib::ustring fname, Glib::ustring path)
		{
			Glib::ustring fpn = path+"/"+fname;
			Glib::RefPtr<Gdk::Pixbuf> im;
			try
			{
				im= Gdk::Pixbuf::create_from_file(fpn);
				return true;
			}
			catch(Glib::Error)
			{
				cout<<fname<<" is no good"<<endl;
				return false;
			}
		}

		virtual ~catImage()
		{
		}

		void setImage(Glib::ustring fname)
		{
			image = Gdk::Pixbuf::create_from_file(fname);
		}

		vector<string> getTags()
		{
			return tags;
		}

		string getTagsAsString()
		{
			string st("");
			for(int i=0;i<tags.size();i++)
			{
				st.append(tags[i]);
				st.append(",");
			}
			return st;

		}

		void addTags(string tag)
		{
			tags = splitTags(tag);
		}
		
		void addMultipleTags(vector<string> atags)
		{
			for(int x=0;x<atags.size()-1;x++)
				tags.push_back(atags[x]);
		}

		string getTitle()
		{
			return title;
		}

		void setTitle(string t)
		{
			title = t;
		}

		Glib::RefPtr<Gdk::Pixbuf> getPixbuf()
		{
			return image;
		}

		void setPixbuf(Glib::RefPtr<Gdk::Pixbuf> i)
		{
			image = i;
		}

		/*
		 * scale the image to width*height
		 * and ignore the aspect ratio
		 *
		 */
		void scale(int width, int height,bool forceRe=false)
		{
			sw = width;
			sh = height;
			scaledInstance = image->scale_simple(width,height,
						Gdk::INTERP_BILINEAR);
			hsi=true;
		}

		/*
		 * automatically scales the image to
		 * fit within a width*height box as
		 * much as possible without altering
		 * the aspect ratio
		 *
		 */
		void fitInto(int width, int height, bool forceRe=false)
		{
			if(hsi&&!forceRe)
			{
			}
			else
			{
				int nw,nh;
				double ar;
				int ow = image->get_width();
				int oh = image->get_height();
	
				if(ow > oh)
				{
					nw = width;
					ar = (double)width/(double)ow;
					nh = (int)(oh * ar);
				}
				else
				{
					nh = height;
					ar = (double)nh/(double)oh;
					nw = (int)(ow * ar);
				}

				//cout<<"final aspect ratio should be"<<endl;
				//cout<<nw<<"x"<<nh<<endl;

				sw = nw;
				sh = nh;

				scaledInstance = image->scale_simple(nw,nh,
							Gdk::INTERP_BILINEAR);
				hsi=true;
			}
		}

		void caption(string ctext)
		{
			textFactory tf(image->get_width(),image->get_height(),
					0xAf,0xAF,0xAF,0x0);
			tf.makeWatermarkImage(ctext,45.0);
			Image* wmim = tf.getWatermark();
		       	imImage.composite(*wmim,CenterGravity,AddCompositeOp);
			string comprm("rm ");
			imImage.write(pathname+".composite");

			image = Gdk::Pixbuf::create_from_file(
					pathname+".composite");

			comprm.append(pathname.c_str());
			comprm.append(".composite");
			system(comprm.c_str());
		}

		void makeAnnotation(string annotext)
		{
			//imImage.boxColor(ColorRGB(0.0,0.0,0.0));
			imImage.fontPointsize(15);
			imImage.border("0x20+0+10");
			imImage.annotate(annotext,SouthGravity);
			string comprm("rm ");
			imImage.write(pathname+".composite");

			image = Gdk::Pixbuf::create_from_file(
					pathname+".composite");

			comprm.append(pathname.c_str());
			comprm.append(".composite");
			system(comprm.c_str());
		}


		Glib::RefPtr<Gdk::Pixbuf> getScaledInstance()
		{
			return scaledInstance;
		}

		int insertImage()
		{

		}
};
#endif
